package com.hx.reflect.example;

import com.hx.reflect.bean.Student;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;

/**
 * @author jxlgcmh
 * @date 2020-08-16 15:29
 * @description
 */
public class Main {
    public static void main(String[] args) {
        Student student = new Student();
        student.setId(1);
        student.setName("Lily");
        String string = Main.toString(student);
        System.out.println("转为String后的结果：" + string);
        Student parse = (Student) Main.toObj(string);
        System.out.println("转回的student对象" + parse);

    }

    /**
     * 将对象转为字符串
     *
     * @param o
     * @return
     */
    public static String toString(Object o) {
        try {
            Class<?> clazz = o.getClass();
            StringBuilder sb = new StringBuilder();
            // 最先放入类名
            sb.append(clazz.getName() + "\n");
            for (Field field : clazz.getDeclaredFields()) {
                if (!field.isAccessible()) {
                    field.setAccessible(true);
                }
                sb.append(field.getName() + "=" + field.get(o).toString() + "\n");
            }
            return sb.toString();
        } catch (Exception e) {
            throw new RuntimeException();
        }
    }

    /**
     * 将字符串转为对象
     *
     * @param string
     * @return
     */
    public static Object toObj(String string) {
        try {
            String[] splits = string.split("\n");
            if (splits.length < 0) {
                throw new IllegalArgumentException(string);
            }
            Class<?> clazz = Class.forName(splits[0]);
            Object instance = clazz.newInstance();
            if (splits.length > 1) {
                for (int i = 1; i < splits.length; i++) {
                    String[] map = splits[i].split("=");
                    if (map.length != 2) {
                        throw new IllegalArgumentException(splits[i]);
                    }
                    Field field = clazz.getDeclaredField(map[0]);
                    if (!field.isAccessible()) {
                        field.setAccessible(true);
                    }
                    setFieldValue(field, instance, map[1]);
                }
            }
            return instance;
        } catch (Exception e) {
            throw new RuntimeException();
        }
    }


    private static void setFieldValue(Field field, Object instance, String value) {
        try {
            Class<?> type = field.getType();
            if (type == byte.class) {
                field.setByte(instance, Byte.parseByte(value));
            } else if (type == short.class) {
                field.setShort(instance, Short.parseShort(value));
            } else if (type == char.class) {
                field.setChar(instance, value.charAt(0));
            } else if (type == int.class) {
                field.setInt(instance, Integer.parseInt(value));
            } else if (type == float.class) {
                field.setFloat(instance, Float.parseFloat(value));
            } else if (type == double.class) {
                field.setDouble(instance, Double.parseDouble(value));
            } else if (type == long.class) {
                field.setLong(instance, Long.parseLong(value));
            } else if (type == boolean.class) {
                field.setBoolean(instance, Boolean.parseBoolean(value));
            } else if (type == String.class) {
                field.set(instance, value);
            } else {
                Constructor<?> constructor = type.getConstructor(new Class[]{String.class});
                field.set(instance, constructor.newInstance(value));
            }
        } catch (IllegalAccessException | InstantiationException | InvocationTargetException | NoSuchMethodException e) {
            e.printStackTrace();
        }
    }
}
